import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
import torch
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import torch.nn as nn
import torch.nn.functional as F
from PIL import Image

class HandwritingSignatureCNN(nn.Module):
    def __init__(self):
        super(HandwritingSignatureCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)  # 增加卷积层
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(128 * 8 * 8, 512)  # 调整全连接层输入大小
        self.fc2 = nn.Linear(512, 2)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.pool(F.relu(self.conv3(x)))  # 添加第三层卷积
        x = x.view(-1, 128 * 8 * 8)  # 展平
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

transform = transforms.Compose([
    transforms.Grayscale(),
    transforms.Resize((64, 64)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(10),
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
    transforms.RandomAffine(degrees=10, translate=(0.1, 0.1), scale=(0.9, 1.1), shear=10),  # 随机仿射变换
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5], std=[0.5])
])

# 加载整个模型
model = torch.load('handwriting_signature_cnn.pth')
model.eval()  # 设置为评估模式

# 加载测试数据
test_data = ImageFolder('processed/test', transform=None)
test_data_transform = ImageFolder('processed/test', transform=transform)
test_loader = DataLoader(test_data_transform, batch_size=1, shuffle=False)  # batch_size设为1，逐张图片处理

# 获取标签的名字
class_names = test_data_transform.classes

# 循环读取每张图片，显示和预测
for idx, (inputs, labels) in enumerate(test_loader):
    # 进行预测
    with torch.no_grad():
        outputs = model(inputs)
        _, predicted = torch.max(outputs, 1)

    predicted_class = class_names[predicted.item()]  # 获取预测类别名称
    true_class = class_names[labels.item()]  # 获取真实类别名称
    plt.title(f"预测结果: {predicted_class}")
    # 获取原始图片路径
    img_path = test_data.samples[idx][0]  # 获取原始图片路径
    img = Image.open(img_path)
    plt.imshow(img, cmap='gray')  # 显示图片
    plt.axis('off')  # 关闭坐标轴
    plt.show()

    # 打印预测结果
    print(f"Predicted: {predicted_class}, True Label: {true_class}")
